# -*- coding: utf-8 -*-
"""
定时更新用户公众号的access_token

"""
import json
import time
from datetime import datetime

import redis
import requests
import requests.packages.urllib3

requests.packages.urllib3.disable_warnings()

fmt = '%Y-%m-%d %H:%M:%S'

def curr_now():
    return datetime.now().strftime(fmt)

class WechatAccessTokenUpdater(object):

    WX_TOKEN_API = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"
    WX_JSTICKET_API = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi"

    def __init__(self):

        self.redis = redis.StrictRedis(host="localhost", port=6379)

        # 设置当前超时时间, 1小时 1 * 60 * 60, 全局使用，避免每次使用int(time.time()),产生时间误差
        self.curr_time = int(time.time())
        self.expired_in = 7200

        # errcode 出现refreshtoken过期，或超出api调用上线 直接置为无效
        # 45009: reach max api daily quota limit hint
        # 61023: refresh_token is invalid hint
        # 61003: component is not authorized by this account hint
        self.errcode_list = [45009, 61023, 61003]

        self.wechat = {"appid": "wx9bb41ce06a907294",
                       "appsecret": "f574c4f8db657122ce2b8edf863dca94",
                       "token": "q37f1cd03cb111e5a2be00163e004a2r",
                       "aeskey": "qi7Hpyni71zm4PrJgqvCEkc5Qw6dcsZPLtZjk3upWTb"}

        self.redis_key_wechat = "kt:wechat_public_token_1"

    def get_access_token(self):
        try:
            url = self.WX_TOKEN_API % (self.wechat.get("appid"), self.wechat.get("appsecret"))

            print "{0} url:{1}".format(curr_now(), url)

            response = requests.get(url, verify=False)

            self._handler_access_token(response)

        except:
            print "{0} get_access_token except".format(curr_now())

    def _handler_access_token(self, response):

        try:

            token = json.loads(response.content.decode('utf-8'))

            print("{0} access_token:{1}".format(curr_now(), token))

            if "errcode" not in token:

                token.update({"access_token": token.get("access_token"),
                              "access_token_create_time": self.curr_time
                              })

                self.get_jsticket(token)

            else:
                print "{0} get access_token failed, {1}!".format(curr_now(), token)

        except Exception as e:
            print e
            print "{0} _handler_access_token except".format(curr_now())

    def get_jsticket(self, token):
        try:
            url = self.WX_JSTICKET_API % token.get("access_token")

            print "{0} jsticket url:{1}".format(curr_now(), url)

            response = requests.get(url, verify=False)

            self._handler_jsticket(token, response)
        except:
            print "{0} get_jsticket except".format(curr_now())

    def _handler_jsticket(self, token, response):
        try:
            print "{0} jsticket response.content {1}".format(curr_now(), response.content)
            jsticket = json.loads(response.content.decode('utf-8'))

            token.update({"jsapi_ticket": jsticket["ticket"] or ''})

            self.wechat.update(token)

        except Exception as e:
            print e
            print "{0} _handler_jsticket except".format(curr_now())

        finally:
            # update
            self.redis.setex(self.redis_key_wechat, self.expired_in, json.dumps(self.wechat))

if __name__ == '__main__':
    wechatAccessTokenUpdater = WechatAccessTokenUpdater()
    wechatAccessTokenUpdater.get_access_token()